package org.hales.security;
import org.hales.common.ServerResponse;
import org.hales.common.Enum;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.hales.service.UserService;
import org.hales.util.JwtUtil;
import org.hales.vo.UserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@Component("loginSuccessHandler")
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private UserService userService;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        logger.info("登录成功2");
        UserInfoBean userInfoBean = (UserInfoBean) authentication.getPrincipal();
        String password = httpServletRequest.getParameter("password");
        //安全登录成功，调用正常登录流程
        ServerResponse<UserVO> serverResponse =  userService.LoginSecuritySuccess(userInfoBean,password);
        //生成tocken令牌
        String token = JwtUtil.createToken(userInfoBean.getUsername());

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + serverResponse.getData().getRoleId()));
        grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ACTIVITI_USER"));
        grantedAuthorities.add(new SimpleGrantedAuthority("GROUP_activitiTeam"));

        //4、如果能返回用户信息,将用户信息存入Authentication中，放行。
        // 因为开启了session,SecurityContextHolder.getContext() 是有值的，存不存无所谓（用到jwt时放开）
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userInfoBean.getUsername(), null, grantedAuthorities);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);


        serverResponse.getData().setToken(token);
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.getWriter().write(objectMapper.writeValueAsString(ServerResponse.createBySuccess("登录成功",serverResponse)));
    }

    /**
     * 计算密码强度
     *
     * @param password 密码字符串
     * @return
     */
    private Enum.PasswordStrength checkPasswordStrength(String password) {
        // 空字符串强度值为0
        if (password.equals("")) {
            return Enum.PasswordStrength.INVALID;
        }
        // 长度小于8或者大于20的密码
        if (password.length() < 8 || password.length() > 20) {
            return Enum.PasswordStrength.INVALID;
        }

        // 字符统计
        int iNum = 0, iLtt = 0, iSym = 0;
        for (char c : password.toCharArray()) {
            if (c >= '0' && c <= '9') {
                iNum++;
            } else if (c >= 'a' && c <= 'z') {
                iLtt++;
            } else if (c >= 'A' && c <= 'Z') {
                iLtt++;
            } else {
                iSym++;
            }
        }
        if (iLtt == 0 && iSym == 0) {
            return Enum.PasswordStrength.WEAK; // 纯数字密码
        }
        if (iNum == 0 && iLtt == 0) {
            return Enum.PasswordStrength.WEAK; // 纯符号密码
        }
        if (iNum == 0 && iSym == 0) {
            return Enum.PasswordStrength.WEAK; // 纯字母密码
        }
        if (iLtt == 0) {
            return Enum.PasswordStrength.NORMAL; // 数字和符号构成的密码
        }
        if (iSym == 0) {
            return Enum.PasswordStrength.NORMAL; // 数字和字母构成的密码
        }
        if (iNum == 0) {
            return Enum.PasswordStrength.NORMAL; // 字母和符号构成的密码
        }

        return Enum.PasswordStrength.STRONG; // 由数字、字母、符号构成的密码
    }
}
